package com.dupf.common.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.*;

/**
 * @author wugaoping
 */
public class DateUtil {

    private static int offSet = Calendar.getInstance().getTimeZone().getRawOffset() / 1000;

    public static ZoneOffset zoneOffset = ZoneOffset.ofTotalSeconds(offSet);

    /**
     * 获取当前时间的秒数
     *
     * @return
     */
    public static int getTime() {
        return (int) (System.currentTimeMillis() / 1000L);
    }

    public static int getGMT() {
        return getTime() - offSet;
    }

    public static int getOffSet() {
        return offSet;
    }

    public static int getSecondsPerDay() {
        return (24 * 60 * 60);
    }

    public static String getStrDate(Integer intDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return stringDateFormat(intDate, sdf);
    }

    public static String stringDateFormat(Integer intDate, SimpleDateFormat sdf) {
        String date = null;
        if (intDate != null) {
            try {
                date = sdf.format(new Date((long) intDate * 1000));
            } catch (Exception e) {
                e.printStackTrace();
                date = intDate.toString();
            }
        }
        return date;
    }

    public static String getStrMonth(Integer intDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        return stringDateFormat(intDate, sdf);
    }

    public static String getStrMonthDay(Integer intDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return stringDateFormat(intDate, sdf);
    }

    public static String getStrYearWeek(Integer intDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyww");
        return stringDateFormat(intDate, sdf);
    }

    /**
     * 获取时：分时间格式。如 09:12
     */
    public static String getHourAndMinute(Integer timestamp) {
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
        return stringDateFormat(timestamp, format);
    }


    /**
     * 指定时间的毫秒表示
     *
     * @param t
     * @param pattern
     * @return
     */
    public static long timeop(String t, String pattern) {
        // 传入的参数要与yyyyMMddHH的格式相同 "yyyyMMddHH"
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, Locale.SIMPLIFIED_CHINESE);
        Date date2 = null;
        try {
            date2 = simpleDateFormat.parse(t);
        } catch (ParseException e) {
        }

        return date2.getTime();
    }

    /**
     * 是否为同一天
     *
     * @param time1
     * @param time2
     * @return
     */
    public static boolean isSameDay(Integer time1, Integer time2) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTimeInMillis(time1 * 1000L);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTimeInMillis(time2 * 1000L);

        boolean isSameDay = calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH)
                && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
                && calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);

        return isSameDay;
    }

    /**
     * 2个时间的间隔天数
     *
     * @param time1
     * @param time2
     * @return
     */
    public static int dayDiff(Integer time1, Integer time2) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTimeInMillis(time1 * 1000L);
        setTimeToMidnight(calendar1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTimeInMillis(time2 * 1000L);
        setTimeToMidnight(calendar2);

        return millisToDays(Math.abs(calendar1.getTimeInMillis() - calendar2.getTimeInMillis()));
    }

    private static int millisToDays(long intervalMs) {
        return (int) (intervalMs / (1000 * 86400));
    }

    private static void setTimeToMidnight(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
    }

    public static Integer getAge(Integer birthday, Integer birthdaytype) {
        if ((birthday == null) || (birthdaytype == null)) {
            return null;
        }

        // TODO: 阴历先粗略转换成阳历
        if (birthdaytype == 2) {
            birthday += 30 * 24 * 60 * 60;
        }

        Calendar cal = Calendar.getInstance();
        int currentYear = cal.get(Calendar.YEAR);

        cal.setTimeInMillis(birthday * 1000);
        int birthYear = cal.get(Calendar.YEAR);

        return currentYear - birthYear;
    }

    public static Integer getMinBirthday(Integer age) {
        if (age == null) {
            return null;
        }

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - age);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DATE, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        return (int) (cal.getTimeInMillis() / 1000);
    }

    public static Integer getMaxBirthday(Integer age) {
        if (age == null) {
            return null;
        }

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - age);

        return (int) (cal.getTimeInMillis() / 1000);
    }

    public static void main(String[] args) {
        System.out.println(getMinBirthday(1));
        System.out.println(getMaxBirthday(1));
    }

    /**
     * 根据生日求年齡
     *
     * @param birthday
     * @return
     */
    public static Integer getAge(Integer birthday) {

        Integer age = 0;
        try {
            if (birthday != null) {

                Calendar now = Calendar.getInstance();
                Calendar birthDay = Calendar.getInstance();
                birthDay.setTimeInMillis(birthday * 1000L);

                if (now.compareTo(birthDay) == -1) {
                    throw new IllegalArgumentException("The birthDay is before Now");
                }

                Integer yearNow = now.get(Calendar.YEAR);
                Integer monthNow = now.get(Calendar.MONTH);
                Integer dayNow = now.get(Calendar.DAY_OF_MONTH);

                Integer yearBirth = birthDay.get(Calendar.YEAR);
                Integer monthBirth = birthDay.get(Calendar.MONTH);
                Integer dayBirth = birthDay.get(Calendar.DAY_OF_MONTH);

                age = yearNow - yearBirth;
                if (monthNow <= monthBirth) {
                    if (monthNow.equals(monthBirth)) {
                        if (dayNow < dayBirth) {
                            age--;
                        }
                    } else {
                        age--;
                    }
                }

            }

        } catch (Exception e) {
            return age;
        }

        return age;
    }

    public static Integer getDayStartTime(Integer datetime) {
        LocalDateTime ldt = DateUtil.getLocalDateTime(datetime);
        return getTimestamp(ldt.with(LocalTime.MIN));
    }

    /**
     * 获取一天最小时间
     */
    public static Integer getDayStartTime(LocalDateTime ldt) {
        return getTimestamp(ldt.with(LocalTime.MIN));
    }

    public static Integer getDayEndTime(Integer datetime) {
        LocalDateTime ldt = DateUtil.getLocalDateTime(datetime);
        return getTimestamp(ldt.with(LocalTime.MAX));
    }

    public static Integer getDayEndTime(LocalDateTime ldt) {
        return getTimestamp(ldt.with(LocalTime.MAX));
    }

    /**
     * 将年月转为yyyyMM
     *
     * @param year
     * @param month
     * @return
     */
    public static String getYearMo(Integer year, Integer month) {
        LocalDate date = LocalDate.of(year, month, 1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
        return formatter.format(date);
    }

    /**
     * 将年月转为yyyyMMdd
     *
     * @param date
     * @return
     */
    public static String getStrYMD(LocalDate date) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        return formatter.format(date);
    }

    /**
     * 将年月转为yyyyMM整数
     *
     * @param year
     * @param month
     * @return
     */
    public static Integer getIntYearMonth(Integer year, Integer month) {
        LocalDate date = LocalDate.of(year, month, 1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
        return Integer.parseInt(formatter.format(date));
    }

    /**
     * 将int时间戳转为 LocalDateTime
     *
     * @param intDate
     * @return
     */
    public static LocalDateTime getLocalDateTime(Integer intDate) {

        LocalDateTime dateTime = null;
        if (intDate != null) {
            try {
                // dateTime =
                // LocalDateTime.ofInstant(Instant.ofEpochMilli((long) intDate *
                // 1000),
                // ZoneId.of("Asia/Shanghai"));
                dateTime = LocalDateTime.ofEpochSecond(intDate, 0, ZoneOffset.ofTotalSeconds(offSet));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return dateTime;
    }

    /**
     * 将int时间戳转为 LocalDate
     *
     * @param intDate
     * @return
     */
    public static LocalDate getLocalDate(Integer intDate) {

        LocalDate ld = null;
        if (intDate != null) {
            try {
                LocalDateTime ldt = getLocalDateTime(intDate);
                ld = ldt.toLocalDate();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return ld;
    }

    /**
     * 将String转为 LocalDate
     *
     * @param date yyyyMMdd
     * @return
     */
    public static LocalDate convertStrToLocalDate(String date) {

        LocalDate ld = null;
        if (date != null) {
            try {
                DateTimeFormatter formatter =
                        DateTimeFormatter.ofPattern("yyyyMMdd");
                ld = LocalDate.parse(date, formatter);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return ld;
    }

    /**
     * 将LocalDateTime转为int时间戳
     *
     * @param localDateTime
     * @return
     */
    public static int getTimestamp(LocalDateTime localDateTime) {

        int result = 0;
        if (localDateTime != null) {
            try {
                result = (int) localDateTime.toEpochSecond(ZoneOffset.ofTotalSeconds(offSet));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 获取一个月中周一的列表，如果当月一号在星期四之后，则一号所在这一周划入上个月的最后一周
     *
     * @param date
     * @return
     */
    public static List<LocalDateTime> getWeekStartDateListOfMonth(LocalDateTime date) {

        List<LocalDateTime> list = new ArrayList<>();
        LocalDateTime thursday = date.with(DayOfWeek.THURSDAY);

        LocalDateTime initDate = LocalDateTime.of(date.getYear(), date.getMonthValue(), 1, 0, 0, 0);
        if (thursday.getMonthValue() != date.getMonthValue() || thursday.getYear() != date.getYear()) {
            if (date.isAfter(thursday)) {
                initDate = LocalDateTime.of(date.getYear(), date.getMonthValue(), 1, 0, 0, 0);
            } else {
                initDate = LocalDateTime.of(thursday.getYear(), thursday.getMonthValue(), 1, 0, 0, 0);
            }
        }

        thursday = initDate.with(DayOfWeek.THURSDAY);
        LocalDateTime nextThursday = initDate.with(DayOfWeek.THURSDAY);

        LocalDateTime nextMonth = initDate.plusMonths(1);

        if (initDate.isAfter(thursday)) {
            nextThursday = thursday.plusWeeks(1);
        }

        while (nextMonth.isAfter(nextThursday)) {
            list.add(nextThursday.with(DayOfWeek.MONDAY));
            nextThursday = nextThursday.plusWeeks(1);
        }

        return list;
    }

    /**
     * 获取一个月中周一的列表，如果当月一号在星期四之后，则一号所在这一周划入上个月的最后一周 （具体日期）
     *
     * @param date
     * @return
     */
    public static List<LocalDateTime> getWeekStartDateListOfMonthByLdt(LocalDateTime date) {

        LocalDateTime thursday = date.with(DayOfWeek.THURSDAY);

        LocalDateTime initDate = LocalDateTime.of(date.getYear(), date.getMonthValue(), 1, 0, 0, 0);
        if (thursday.getMonthValue() != date.getMonthValue() || thursday.getYear() != date.getYear()) {
            initDate = LocalDateTime.of(thursday.getYear(), thursday.getMonthValue(), 1, 0, 0, 0);
        }

        return getWeekStartDateListOfMonth(initDate);
    }

    /**
     * 获取这一天在当月中的第几周
     *
     * @param localDateTime
     * @param weekList
     * @return
     */
    public static Integer getWeekOfMonth(LocalDateTime localDateTime, List<LocalDateTime> weekList) {

        Integer currentWeek = 0;

        for (int i = 0; i < weekList.size(); i++) {
            LocalDateTime ldt = weekList.get(i);
            if (!localDateTime.isAfter(ldt)) {
                break;
            }

            currentWeek++;
        }

        return currentWeek;
    }

    /**
     * 获取LocalDate日期的字符串格式 格式为：20170320
     *
     * @param date
     * @return
     */
    public static String getStrFromLocalDate(LocalDate date) {
        return date.toString().replaceAll("-", "");
    }

    /**
     * 取得季度月
     *
     * @param date
     * @return
     */
    public static LocalDateTime[] getSeasonDate(LocalDateTime date) {
        LocalDateTime[] season = new LocalDateTime[3];

        int year = date.getYear();

        int nSeason = getSeason(date);
        if (nSeason == 1) {// 第一季度
            season[0] = LocalDateTime.of(year, Month.JANUARY, 1, 0, 0, 0);
            season[1] = LocalDateTime.of(year, Month.FEBRUARY, 1, 0, 0, 0);
            season[2] = LocalDateTime.of(year, Month.MARCH, 1, 0, 0, 0);
        } else if (nSeason == 2) {// 第二季度
            season[0] = LocalDateTime.of(year, Month.APRIL, 1, 0, 0, 0);
            season[1] = LocalDateTime.of(year, Month.MAY, 1, 0, 0, 0);
            season[2] = LocalDateTime.of(year, Month.JUNE, 1, 0, 0, 0);
        } else if (nSeason == 3) {// 第三季度
            season[0] = LocalDateTime.of(year, Month.JULY, 1, 0, 0, 0);
            season[1] = LocalDateTime.of(year, Month.AUGUST, 1, 0, 0, 0);
            season[2] = LocalDateTime.of(year, Month.SEPTEMBER, 1, 0, 0, 0);
        } else if (nSeason == 4) {// 第四季度
            season[0] = LocalDateTime.of(year, Month.OCTOBER, 1, 0, 0, 0);
            season[1] = LocalDateTime.of(year, Month.NOVEMBER, 1, 0, 0, 0);
            season[2] = LocalDateTime.of(year, Month.DECEMBER, 1, 0, 0, 0);
        }
        return season;
    }

    /**
     * 取得季度的第一天
     *
     * @param date
     * @return
     */
    public static LocalDateTime getSeasonFirstDate(LocalDateTime date) {

        int year = date.getYear();

        int nSeason = getSeason(date);
        if (nSeason == 1) {// 第一季度
            return LocalDateTime.of(year, Month.JANUARY, 1, 0, 0, 0);
        } else if (nSeason == 2) {// 第二季度
            return LocalDateTime.of(year, Month.APRIL, 1, 0, 0, 0);
        } else if (nSeason == 3) {// 第三季度
            return LocalDateTime.of(year, Month.JULY, 1, 0, 0, 0);
        } else if (nSeason == 4) {// 第四季度
            return LocalDateTime.of(year, Month.OCTOBER, 1, 0, 0, 0);
        }
        return null;
    }

    /**
     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
     *
     * @param date
     * @return
     */
    public static int getSeason(LocalDateTime date) {

        int season = 0;

        Month month = date.getMonth();
        switch (month) {
        case JANUARY:
        case FEBRUARY:
        case MARCH:
            season = 1;
            break;
        case APRIL:
        case MAY:
        case JUNE:
            season = 2;
            break;
        case JULY:
        case AUGUST:
        case SEPTEMBER:
            season = 3;
            break;
        case OCTOBER:
        case NOVEMBER:
        case DECEMBER:
            season = 4;
            break;
        default:
            break;
        }
        return season;
    }

    /**
     * 获取月份对应的中文
     *
     * @param intMonth
     * @return
     */
    public static String getMonthName(Integer intMonth) {

        String monthName = "";

        Month month = Month.of(intMonth);
        switch (month) {
        case JANUARY:
            monthName = "一月";
            break;
        case FEBRUARY:
            monthName = "二月";
            break;
        case MARCH:
            monthName = "三月";
            break;
        case APRIL:
            monthName = "四月";
            break;
        case MAY:
            monthName = "五月";
            break;
        case JUNE:
            monthName = "六月";
            break;
        case JULY:
            monthName = "七月";
            break;
        case AUGUST:
            monthName = "八月";
            break;
        case SEPTEMBER:
            monthName = "九月";
            break;
        case OCTOBER:
            monthName = "十月";
            break;
        case NOVEMBER:
            monthName = "十一月";
            break;
        case DECEMBER:
            monthName = "十二月";
            break;
        default:
            break;
        }
        return monthName;
    }

    /**
     * 获取date是当月的第几周
     *
     * @param date
     */
    public static Integer getWeekNoOfMonth(LocalDateTime date) {
        int year = date.getYear();
        int month = date.getMonthValue();
        int dayOfMonth = date.getDayOfMonth();
        int days = date.toLocalDate().getDayOfMonth();
        int count = 0;

        for (int i = 1; i <= days; i++) {
            LocalDate date2 = LocalDate.of(year, month, i);
            int k = date2.getDayOfWeek().getValue();
            boolean returnFlag = false;
            if (i == dayOfMonth) {
                returnFlag = true;
            }
            if (k == 7) {// 若当天是周日
                count++;
                if (returnFlag) {
                    break;
                }
                // System.out.println("-----------------------------------");
                // System.out.println("第" + count + "周");
                // if (i - 6 <= 1) {
                // System.out.println("本周开始日期:" + date + "-" + 1);
                // } else {
                // System.out.println("本周开始日期:" + date + "-" + (i - 6));
                // }
                // System.out.println("本周结束日期:" + date + "-" + i);
                // System.out.println("-----------------------------------");
            }
            if (k != 7 && i == days) {// 若是本月最好一天，且不是周日
                count++;
                if (returnFlag) {
                    break;
                }
                // System.out.println("-----------------------------------");
                // System.out.println("第" + count + "周");
                // System.out.println("本周开始日期:" + date + "-" + (i - k + 2));
                // System.out.println("本周结束日期:" + date + "-" + i);
                // System.out.println("-----------------------------------");
            }

            if (returnFlag) {
                count++;
                break;
            }
        }
        return count;
    }

    /**
     * 根据月份获取月份天数
     */
    public static Integer getDaysOfMonth(Integer year, Integer month) {

        Integer days = 0;
        switch (month) {
        case 2: {
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                days = 29;
            } else {
                days = 28;
            }
            break;
        }
        case 4:
            days = 30;
            break;
        case 6:
            days = 30;
            break;
        case 9:
            days = 30;
            break;
        case 11:
            days = 30;
            break;
        default:
            days = 31;
            break;
        }
        return days;
    }

    /**
     * 获取每月所有周一到周日的日期，不足从上个月和下个月补足
     *
     * @throws ParseException
     */
    public static List<Date> getAllDateOfMonth(Integer year, Integer month) throws ParseException {

        List<Date> list = new ArrayList<>();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        sdf.setLenient(false);

        // 月初日期
        Date monthStartDate = sdf.parse(year + "/" + month + "/" + "1");

        // 获取月初日期星期几
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(monthStartDate);
        int intWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (intWeek <= 0) {
            intWeek = 7;
        }

        // 获取周一日期，从上月补齐
        Calendar c = Calendar.getInstance();
        c.setTime(monthStartDate); // 设置当前日期
        c.add(Calendar.DATE, 1 - intWeek); // 日期加1天
        monthStartDate = c.getTime();

        // 获取月末日期
        Date monthEndDate = sdf.parse(year + "/" + month + "/" + getDaysOfMonth(year, month));

        // 获取月末日期星期几
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(monthEndDate);
        int intWeek2 = calendar2.get(Calendar.DAY_OF_WEEK) - 1;
        if (intWeek2 <= 0) {
            intWeek2 = 7;
        }

        // 获取周日日期，从下月补齐
        Calendar c2 = Calendar.getInstance();
        c2.setTime(monthEndDate); // 设置当前日期
        c2.add(Calendar.DATE, 7 - intWeek2); // 日期加1天
        monthEndDate = c2.getTime();

        // 开始时间必须小于结束时间

        Date date = monthStartDate;
        while (date.getTime() <= monthEndDate.getTime()) {
            list.add(date);
            c.setTime(date);
            c.add(Calendar.DATE, 1); // 日期加1天
            date = c.getTime();
        }

        return list;
    }

    /**
     * 将日期格式转为时间戳
     *
     * @param date
     * @return
     */
    public static Integer pasrDateToTime(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        return DateUtil.getTimestamp(LocalDateTime.parse(sdf.format(date)));
    }

    /**
     * 将"yyyy/MM/dd HH:mm:ss"转换为时间戳
     *
     * @param dateStr 日期时间字符串
     * @return 时间戳，秒
     */
    public static Integer parseStringDateToTimeStamp(String dateStr) {
        String format = getDateFormatString(dateStr);
        if (format == null) {
            return null;
        }
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);
        TemporalAccessor parse = dtf.parse(dateStr);

        return DateUtil.getTimestamp(LocalDateTime.from(parse));

    }

    /**
     * 将"yyyy/MM/dd HH:mm:ss"转换为LocalDateTime
     *
     * @param dateStr 日期时间字符串
     * @return LocalDateTime
     */
    public static LocalDateTime parseStringDateToLocalDateTime(String dateStr) {
        String format = getDateFormatString(dateStr);
        if (format == null) {
            return null;
        }

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);
        TemporalAccessor parse = dtf.parse(dateStr);

        return LocalDateTime.from(parse);

    }

    /**
     * 根据字符串日期获取日期格式化字符串
     * @param dateStr 日期字符串
     * @return
     */
    public static String getDateFormatString(String dateStr) {
        String format = null;
        if(dateStr.matches("(\\d{1,4})/(\\d|0\\d|1[0-2])/(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d)")) {
            format = "y/M/d H:m";
        }
        if(dateStr.matches("(\\d{1,4})-(\\d|0\\d|1[0-2])-(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d)")) {
            format = "y-M-d H:m";
        }
        if(dateStr.matches("(\\d{1,4})/(\\d|0\\d|1[0-2])/(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)")) {
            format = "y/M/d H:m:s";
        }
        if(dateStr.matches("(\\d{1,4})-(\\d|0\\d|1[0-2])-(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)")) {
            format = "y-M-d H:m:s";
        }
        if(dateStr.matches("(\\d{1,4})/(\\d|0\\d|1[0-2])/(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)\\.\\d{3}")) {
            format = "y/M/d H:m:s.SSS";
        }
        if(dateStr.matches("(\\d{1,4})/(\\d|0\\d|1[0-2])/(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)\\.\\d{2}")) {
            format = "y/M/d H:m:s.SS";
        }
        if(dateStr.matches("(\\d{1,4})/(\\d|0\\d|1[0-2])/(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)\\.\\d")) {
            format = "y/M/d H:m:s.S";
        }
        if(dateStr.matches("(\\d{1,4})-(\\d|0\\d|1[0-2])-(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)\\.\\d{3}")) {
            format = "y-M-d H:m:s.SSS";
        }
        if(dateStr.matches("(\\d{1,4})-(\\d|0\\d|1[0-2])-(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)\\.\\d{2}")) {
            format = "y-M-d H:m:s.SS";
        }
        if(dateStr.matches("(\\d{1,4})-(\\d|0\\d|1[0-2])-(\\d|0\\d|[12]\\d|3[01])[ ](\\d|0\\d|1\\d|2[0-3]):(\\d|[0-5]\\d):(\\d|[0-5]\\d)\\.\\d")) {
            format = "y-M-d H:m:s.S";
        }
        return format;
    }

    /**
     * 获取本月月初时间戳
     *
     * @return 本月1号时间戳
     */
    // TODO:加力速递
    public static Integer getFirstDayTimestampOfThisMonth() {
        LocalDateTime today = LocalDateTime.now();
        Integer month = today.getMonthValue();
        Integer year = today.getYear();
        LocalDateTime firstDayOfThisMonth = LocalDateTime.of(year, month, 1, 0, 0, 0);
        Timestamp timestamp = Timestamp.valueOf(firstDayOfThisMonth);
        return (Integer) (int) (timestamp.getTime() / 1000L);
    }

    /**
     * 获取本月月末时间戳
     *
     * @return 本月月末时间戳
     */
    // TODO:加力速递
    public static Integer getLastDayTimestampOfThisMonth() {
        LocalDateTime today = LocalDateTime.now();
        Integer month = today.getMonthValue();
        Integer year = today.getYear();
        Integer lastDay = getDaysOfMonth(year, month);
        LocalDateTime lastDayOfThisMonth = LocalDateTime.of(year, month, lastDay, 23, 59, 59);
        Timestamp timestamp = Timestamp.valueOf(lastDayOfThisMonth);
        return (Integer) (int) (timestamp.getTime() / 1000L);
    }

    /**
     * 获取月初时间戳
     */
    public static Integer getMonthStartTime(Integer time) {
        LocalDate localDate = DateUtil.getLocalDate(time);
        return DateUtil.getTimestamp(LocalDateTime.of(localDate.withDayOfMonth(1), LocalTime.MIN));
    }

    /**
     * 获取月末时间戳
     */
    public static Integer getMonthEndTime(Integer time) {
        LocalDate localDate = DateUtil.getLocalDate(time);
        return DateUtil.getTimestamp(
                LocalDateTime.of(localDate.withDayOfMonth(1).plusMonths(1).minusDays(1), LocalTime.MAX));
    }

    public static Map<String, Object> parseStrToLocalDate(String dateStr) {
        String format = null;
        //存储日期类型 1、精确到月 2、精确到日
        Integer type = null;

        if (dateStr.matches("(\\d{1,4})/(\\d|0\\d|1[0-2])")) {
            format = "y/M/d";
            dateStr += "/1";
            type = 1;
        } else if (dateStr.matches("(\\d{1,4})-(\\d|0\\d|1[0-2])")) {
            format = "y-M-d";
            dateStr += "-1";
            type = 1;
        } else if (dateStr.matches("(\\d{1,4})/(\\d|0\\d|1[0-2])/(\\d|0\\d|[12]\\d|3[01])")) {
            format = "y/M/d";
            type = 2;
        } else if (dateStr.matches("(\\d{1,4})-(\\d|0\\d|1[0-2])-(\\d|0\\d|[12]\\d|3[01])")) {
            format = "y-M-d";
            type = 2;
        }


        Map<String, Object> resultMap = new HashMap<>();
        if (format == null) {

            String format1 = getDateFormatString(dateStr);
            if (format1 == null) {
                return null;
            }

            DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format1);
            TemporalAccessor parse = dtf.parse(dateStr);

            LocalDateTime ldt = LocalDateTime.from(parse);
            resultMap.put("type", 2);
            resultMap.put("date", ldt.toLocalDate());
        } else {

            DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format);
            TemporalAccessor parse = dtf.parse(dateStr);

            resultMap.put("type", type);
            resultMap.put("date", LocalDate.from(parse));
        }

        return resultMap;
    }

    /**
     * getTodayEndTime
     * 获取今天最后时间
     * @return Date
     */
    public static Date getTodayEndTime(LocalDateTime ltd) {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.YEAR, ltd.getYear());
        todayEnd.set(Calendar.MONTH, ltd.getMonthValue() - 1);
        todayEnd.set(Calendar.DAY_OF_MONTH, ltd.getDayOfMonth());
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

}
